//
//  QRCodeViewController.swift
//  SinaWeibo
//
//  Created by 胡阳 on 16/5/23.
//  Copyright © 2016年 young4ever. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController, UITabBarDelegate {

        /// 扫描容器高度
    @IBOutlet weak var containerHeightCons: NSLayoutConstraint!
        /// 冲击波视图topConstraint
    @IBOutlet weak var scanLineTopCons: NSLayoutConstraint!
        /// 冲击波视图
    @IBOutlet weak var scanLineView: UIImageView!
        /// 自定义的tabBar
    @IBOutlet weak var customTabBar: UITabBar!
        /// 显示结果label
    @IBOutlet weak var resultLabel: UILabel!
    
    /**
     关闭按钮点击
     */
    @IBAction func closeButtonClick(sender: AnyObject) {
        
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    /**
     我的名片按钮点击
     */
    @IBAction func myCardButtonClick() {
        
        let cardVC = QRCodeCardViewController()
        self.navigationController?.pushViewController(cardVC, animated: true)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // 1.设置底部默认视图选中第0个
        customTabBar.selectedItem = customTabBar.items![0]
        customTabBar.delegate = self
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        startAnimation()
        
        scanCode()
    }
    
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        self.scanLineView.layer.removeAllAnimations()
        session.stopRunning()
    }
    
    private func startAnimation()
    {
        // 让约束从顶部开始
        self.scanLineTopCons.constant = -self.containerHeightCons.constant
        self.view.layoutIfNeeded()
        
        // 执行冲击波动画
        UIView.animateWithDuration(2.0) { 
            // 1.修改约束
            self.scanLineTopCons.constant = self.containerHeightCons.constant
            UIView.setAnimationRepeatCount(MAXFLOAT)
            // 2.强制更新界面
            self.view.layoutIfNeeded()
        }
    }
    
    // MARK: - 扫描二维码
    /**
     扫描二维码
     */
    private func scanCode(){
    
        // 1.判断是否能够将输入添加到会话中
        if !session.canAddInput(input) {return}
        // 2.判断是否能够将输出添加到会话中
        if !session.canAddOutput(output) {return}
        // 3.将输入输出添加到会话中
        session.addInput(input)
        session.addOutput(output)
        // 4.设置输出能够解析的数据类型
        // 注意:设置能够解析的数据类型 , 一定要在输出对象添加到会话之后设置,否则会报错
        output.metadataObjectTypes = output.availableMetadataObjectTypes
//        print(output.availableMetadataObjectTypes)
        // 5.设置输出对象的代理, 只要解析成功就会通知代理
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
        // 5.1 添加预览图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        
        previewLayer.addSublayer(drawLayer)
        // 6.告诉session开始扫描
        session.startRunning()
    }

    // MARK: - UITabBarDelegate
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        // 1.修改容器高度
        if item.tag == 1 {
            self.containerHeightCons.constant = 300
        }else {
            self.containerHeightCons.constant = 150
        }
        
        // 2.停止动画
        self.scanLineView.layer.removeAllAnimations()
        
        // 3.重新开始动画
        startAnimation()
    }
    
    // MARK: - 懒加载
        /// 会话
    private lazy var session : AVCaptureSession = AVCaptureSession()
    
        /// 拿到输入设备
    private lazy var input: AVCaptureDeviceInput? = {
        
        let deveice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        
        do{
        
            let input = try AVCaptureDeviceInput(device: deveice)
            return input
        }catch{
            
            print(error)
            return nil
        }
    }()
    
        /// 拿到输出设备
    private lazy var output : AVCaptureMetadataOutput = AVCaptureMetadataOutput()
        /// 预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
        /// 预览图层上的展示二维码边框的图层
    private lazy var drawLayer : CALayer = {
        let layer = CALayer()
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
}

extension QRCodeViewController: AVCaptureMetadataOutputObjectsDelegate {

    // 只要解析到数据就会打印
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!)
    {
        //0.清空二维码的矩形边框<此方法会频繁调用>
        clearCorner()
        
        // 1.获取到秒到的数据
        resultLabel.text = metadataObjects.last?.stringValue
        resultLabel.sizeToFit()
        
        // 2.获取扫描到的位置
        // 2.1 转换坐标
        for object in metadataObjects {
            // 2.1.1 判断当前获取到的数据是否是机器可以识别
            if object is AVMetadataMachineReadableCodeObject {
                // 2.1.2转换
                let codeObject = previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
//                print(codeObject)888
                // 2.1.3绘制图形
                drawCorner(codeObject)
            }
            
        }
    }
    
    /**
     绘制图形
     
     - parameter codeObject: 坐标对象
     */
    private func drawCorner(codeObject:AVMetadataMachineReadableCodeObject)
    {
        if codeObject.corners.isEmpty {
            return
        }
        //1.创建图层
        let layer = CAShapeLayer()
        layer.lineWidth = 4
        layer.strokeColor = UIColor.greenColor().CGColor
        layer.fillColor = UIColor.clearColor().CGColor
        //2.创建路径
        let path = UIBezierPath()
        var point = CGPointZero
        var index: Int = 0
        // 从corners数组中取出第0个元素,将这个字典中的x/y值赋值给point
        CGPointMakeWithDictionaryRepresentation((codeObject.corners[index++] as! CFDictionaryRef), &point)
        path.moveToPoint(point)
        
        while index < codeObject.corners.count {
//            index += 1
            CGPointMakeWithDictionaryRepresentation((codeObject.corners[index++] as! CFDictionaryRef), &point)
            path.addLineToPoint(point)
        }
        path.closePath()
        
        layer.path = path.CGPath
        //3.将图层添加到drawLayer上面
        drawLayer.addSublayer(layer)
    }
    
    private func clearCorner()
    {
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0
        {
            return
        }
        
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}
